{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# Uploading objects to AIS with the SDK"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "pip install aistore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from aistore import Client\n",
    "\n",
    "# Use the client class to get a reference to a named bucket:\n",
    "ais_url = \"http://localhost:8080\"\n",
    "client = Client(ais_url)\n",
    "\n",
    "# All object operations are done within the context of a bucket\n",
    "bucket = client.bucket(\"my-bck\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## There are 4 primary ways to create objects in AIS with the SDK\n",
    "1. object.get_writer().put_content creates an object with raw bytes\n",
    "2. object.get_writer().put_file creates an object from file contents\n",
    "3. object.promote takes files the AIS storage targets can access and promotes them to objects\n",
    "4. bucket.put_files puts an entire directory as multiple objects in AIS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### Object.get_writer().put_content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "data_obj = bucket.object(\"my-data-object\")\n",
    "data_obj.get_writer().put_content(b\"raw bytes content\")\n",
    "bucket.list_objects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### Object.get_writer().put_file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import tempfile\n",
    "\n",
    "# Create a temporary file to demonstrate put_file\n",
    "with tempfile.NamedTemporaryFile() as f:\n",
    "    f.write(b\"content inside of a local file\")\n",
    "    f.flush()\n",
    "    bucket.object(\"my-file-object\").get_writer().put_file(f.name)\n",
    "bucket.list_objects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### Object.promote\n",
    "\n",
    "This method only works if the filepath provided can be accessed by the AIS storage targets. See [the aiatscale.org blog](https://aiatscale.org/blog/2022/03/17/promote) for details on promoting.\n",
    "It will work in a local example if AIS is running on the same machine, shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import shutil\n",
    "\n",
    "# Set up an example folder with multiple files\n",
    "example_dir = Path().absolute().joinpath(\"promote-example\")\n",
    "example_dir.mkdir(exist_ok=True)\n",
    "filenames = [f\"file_{i}\" for i in range(10)]\n",
    "for filename in filenames:\n",
    "    filepath = example_dir.joinpath(filename)\n",
    "    with open(filepath, \"w\") as file:\n",
    "        file.write(\"content in each test file\")\n",
    "# Promote the entire directory (more options available in the docs)\n",
    "bucket.object(\"promoted-object\").promote(str(example_dir))\n",
    "\n",
    "# Delete the example folder\n",
    "shutil.rmtree(example_dir)\n",
    "\n",
    "bucket.list_objects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### Bucket.put_files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Again, set up an example folder with multiple files\n",
    "example_dir = Path().absolute().joinpath(\"put_files-example\")\n",
    "example_dir.mkdir(exist_ok=True)\n",
    "filenames = [f\"file_{i}\" for i in range(10)]\n",
    "for filename in filenames:\n",
    "    filepath = example_dir.joinpath(filename)\n",
    "    with open(filepath, \"w\") as file:\n",
    "        file.write(\"content in each test file\")\n",
    "# Put each file in the entire directory (more options available in the docs, including recursive put)\n",
    "bucket.put_files(str(example_dir), obj_prefix=\"example-put-\")\n",
    "\n",
    "# Delete the example folder\n",
    "shutil.rmtree(example_dir)\n",
    "\n",
    "bucket.list_objects()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "## Append content to an existing object"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Object.get_writer().append_content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an object\n",
    "obj_append = bucket.object(\"my-object\")\n",
    "obj_append.get_writer().put_content(b\"original content\\n\")\n",
    "\n",
    "first_content_to_append = b\"first additional line\\n\"\n",
    "# The handle argument should be an empty string for the first append\n",
    "first_handle = obj_append.append_content(first_content_to_append, \"\", False)\n",
    "\n",
    "second_content_to_append = b\"second additional line\\n\"\n",
    "# Pass the returned first handle as the argument for the next append\n",
    "second_handle = obj_append.append_content(second_content_to_append, first_handle, False)\n",
    "\n",
    "# Pass the returned second handle and specify the flush flag to finalize all appends\n",
    "obj_append.append_content(b\"\", second_handle, True)\n",
    "\n",
    "# Retrieve and print the final content of the object\n",
    "final_content = obj_append.get_reader().read_all()\n",
    "print(final_content.decode(\"utf-8\"))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
